<template>
  <div>
    <el-dialog
      class="avue-dialog my-dialog"
      title="填报"
      :visible.sync="dialogVisible"
      width="45%"
      :before-close="handleClose"
      :close-on-click-modal="false"
    >
      <!-- 表单 -->
      <avue-form ref="form" v-model="form" :option="formOption">
        <template slot-scope="{ dic }" slot="leaderId">
          <el-select
            clearable
            @change="(e) => changeLeader(e, dic)"
            v-model="form.leaderId"
            placeholder="请选择 带班领导"
          >
            <el-option
              v-for="item in dic"
              :key="item.userName"
              :label="item.nickName"
              :value="item.userName"
            >
            </el-option>
          </el-select>
        </template>
      </avue-form>
      <!-- 表格 -->
      <avue-crud
        ref="crud"
        :data="tableData"
        :option="tableOption"
        @row-dblclick="handleRowDBLClick"
        @selection-change="selectionChange"
        :table-loading="loading"
      >
        <template slot="menuLeft">
          <el-button
            size="small"
            icon="el-icon-plus"
            circle
            title="新增"
            @click="addData"
          ></el-button>
          <el-button
            size="small"
            icon="el-icon-delete"
            circle
            title="删除"
            @click="delData"
          ></el-button>
          <!-- <el-button
            icon="el-icon-document-add"
            circle
            title="导入"
            @click="importData"
          >
          </el-button>
          <el-button
            icon="el-icon-download"
            circle
            title="下载导入模板"
            @click="downloadTemplate"
          >
          </el-button>
          <input
            style="opacity: 0; display: none"
            ref="import"
            type="file"
            accept=".xlsx, .xls"
            @input="onImportEx"
          /> -->
        </template>
      </avue-crud>
      <span slot="footer" class="dialog-footer"
        ><el-button
          icon="el-icon-circle-plus-outline"
          size="small"
          type="primary"
          :disabled="tableData.length === 0"
          @click="confirmHandle"
          >保 存</el-button
        >
        <el-button
          icon="el-icon-circle-close"
          size="small"
          @click="$emit('close')"
          >取 消</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import XLSX from "xlsx";
import { mapGetters } from "vuex";
import { getToken } from "@/utils/auth";
import { bsaeUrl } from "@/config/index";
import { getInfo, submit, getUserList } from "@/api/arrangeClasses/fillIn";

const validatePhone = (rule, value, callback) => {
  const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
  if (!reg.test(value)) {
    callback(new Error("请输入正确的联系方式"));
  } else {
    callback();
  }
};

const validateOfficePhone = (rule, value, callback) => {
  const reg = /^(\d{3,4}-)?\d{7,8}$/; // /^\d{7}$/;
  if (!reg.test(value)) {
    callback(new Error("请输入正确的办公电话"));
  } else {
    callback();
  }
};

export default {
  props: {
    row: {
      type: Object,
      default: () => ({}),
    },
    scheduleDay: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      form: {
        deptId: "",
        deptName: "",
        scheduleDay: "",
        leaderId: "",
        leaderName: "",
        leaderPhone: "",
      },
      dialogVisible: true,
      // 表格
      tableData: [],
      // 多选变量
      selection: [],
      // 用户列表
      userList: [],
      loading: false,
    };
  },
  computed: {
    ...mapGetters(["userInfo"]),
    formOption() {
      return {
        emptyBtn: false,
        submitBtn: false,
        labelWidth: 90,
        cellBtn: true,
        column: [
          {
            label: "单位名称",
            prop: "deptName",
            span: 12,
            disabled: true,
          },
          {
            label: "排班日期",
            prop: "scheduleDay",
            span: 12,
            disabled: true,
          },
          {
            label: "排班类型",
            prop: "scheduleType",
            span: 12,
            type: "select",
            props: {
              label: "dictLabel",
              value: "dictValue",
            },
            dicUrl: `${bsaeUrl}/system/dict/data/list?dictType=xmu_schedule_type`,
            dicHeaders: {
              Authorization: "Bearer " + getToken(),
            },
            dicFormatter: (res) => {
              const { rows = [], code } = res;
              return code === 200 ? rows : [];
            },
            disabled: true,
          },
          {
            label: "带班领导",
            prop: "leaderId",
            span: 12,
            type: "select",
            props: {
              label: "nickName",
              value: "userName",
            },
            dicUrl: `${bsaeUrl}/xmu-sys/user/leaderList`,
            dicQuery: {
              deptId: this.userInfo.deptId,
              userId: this.userInfo.userId,
            },
            dicHeaders: {
              Authorization: "Bearer " + getToken(),
            },
            dicFormatter: (res) => {
              const { rows = [], code } = res;
              return code === 200 ? rows : [];
            },
            formslot: true,
            // change
            // blur: ({ item = {} }) => {
            //   const {
            //     phonenumber = "",
            //     nickName = "",
            //     officialPhone = "",
            //   } = item;
            //   console.error("ccccccccccc", item);
            //   this.form.leaderName = nickName;
            //   this.form.leaderPhone = phonenumber;
            //   this.form.leaderOfficePhone = officialPhone;
            //   setTimeout(() => {
            //     this.formatUserData();
            //   }, 400);
            // },
            rules: [
              {
                required: true,
                message: "请选择带班领导",
                trigger: "change",
              },
            ],
            filterable: true,
          },
          {
            label: "联系方式",
            prop: "leaderPhone",
            span: 12,
            rules: [
              {
                required: true,
                validator: validatePhone,
                trigger: "blur",
              },
            ],
          },
          {
            label: "办公电话",
            prop: "leaderOfficialPhone",
            span: 12,
            rules: [
              {
                required: true,
                validator: validateOfficePhone,
                trigger: "blur",
              },
            ],
          },
        ],
      };
    },
    tableOption() {
      return {
        addBtn: false,
        editBtn: false,
        border: true,
        refreshBtn: false,
        columnBtn: false,
        delBtn: false,
        menu: false,
        selection: true,
        tip: false,
        maxHeight: 400,
        column: [
          {
            label: "职工号",
            prop: "userId",
            cell: true,
            readonly: true,
          },
          {
            cell: true,
            label: "排班人员",
            prop: "userId",
            span: 12,
            type: "select",
            props: {
              label: "nickName",
              value: "userName",
              disabled: "disabled",
            },
            dicData: this.userList,
            // dicUrl: `${bsaeUrl}/xmu-sys/user/userList`,
            // dicQuery: {
            //   deptId: 103048, //this.userInfo.deptId,
            //   // userId: this.userInfo.userId,
            // },
            // dicHeaders: {
            //   Authorization: "Bearer " + getToken(),
            // },
            // dicFormatter: (res) => {
            //   const { data = [], code } = res;
            //   this.userList = code === 200 ? data : [];
            //   return code === 200 ? data : [];
            // },
            change: ({ row, value }) => {
              const {
                phonenumber = "",
                nickName = "",
                officialPhone = "",
              } = this.userList.find((item) => item.userName === value) || {};
              row.userName = nickName || "";
              row.phone = phonenumber || "";
              row.officialPhone = officialPhone || "";
              this.formatUserData();
            },
            rules: [
              {
                required: true,
                message: "请选择排班人员",
                trigger: "change",
              },
            ],
            filterable: true,
          },
          {
            label: "办公电话",
            prop: "officialPhone",
            cell: true,
            rules: [
              {
                required: true,
                validator: validateOfficePhone,
                trigger: "blur",
              },
            ],
          },
          {
            label: "移动电话", //"联系方式",
            prop: "phone",
            cell: true,
            rules: [
              {
                required: true,
                validator: validatePhone,
                trigger: "blur",
              },
            ],
          },
          {
            label: "备注",
            prop: "remark",
            cell: true,
          },
        ],
      };
    },
  },
  // watch: {
  //   tableData: {
  //     handler(newArr) {
  //       console.error("newArr", newArr);
  //     },
  //     deep: true,
  //   },
  // },
  methods: {
    handleClose() {
      this.$emit("close");
    },
    // 双击行编辑
    handleRowDBLClick(row) {
      this.$refs.crud.rowCellEdit(row);
    },
    // 新增
    addData() {
      this.tableData.push({
        userName: "",
        userId: "",
        phone: "",
        remark: "",
        officialPhone: "",
        leaderOfficialPhone: "",
        $cellEdit: true,
      });
    },
    // 删除
    delData() {
      const indexs = this.selection.map((v) => v.$index);
      let copyData = [...this.tableData];
      const d = copyData.filter((v) => !indexs.includes(v.$index));
      this.tableData = d;
      this.formatUserData();
    },
    // 多选选中状态
    selectionChange(selection) {
      this.selection = selection;
    },
    // 确定
    async confirmHandle() {
      this.$refs.form.validate((r, done) => {
        done();
        !r && this.$message.error("请完善填报信息!");
        r &&
          this.$refs.crud.validateCellForm().then((res) => {
            if (JSON.stringify(res) === "{}" || !res) {
              this.updateFillInfo();
            } else {
              this.$message.error("请完善填报信息!");
            }
          });
      });
    },
    // 更新填报信息
    async updateFillInfo() {
      const { scheduleTableId, scheduleType } = this.row;
      // 设置参数
      const params = {
        scheduleType,
        pid: scheduleTableId,
        scheduleDay: this.scheduleDay,
        ...this.form,
        scheduleDeptDetailList: this.tableData,
      };
      // 请求
      const { code, msg } = await submit(params);
      // 提示
      if (code === 200) {
        this.$message.success(msg);
        this.$emit("close", "confirm");
      }
    },
    // 数据初始化
    async initData() {
      const { scheduleDeptTableList = [], scheduleTableId } = this.row;
      const result =
        scheduleDeptTableList.find(
          (v) => v.scheduleDay === this.scheduleDay && v.pid === scheduleTableId
        ) || {};
      if (Object.keys(result).length === 0) {
        this.loading = false;
        return;
      }
      // 获取id
      const { scheduleDeptTableId } = result;
      const { code, data = {} } = await getInfo(scheduleDeptTableId);
      if (code === 200) {
        const { scheduleDeptDetailList = [], ...others } = data;
        // 赋值
        this.tableData = scheduleDeptDetailList;
        this.form = {
          ...this.form,
          ...others,
        };
      }
      this.loading = false;
    },
    // 导入触发
    importData() {
      this.$refs.import.value = "";
      this.$refs.import.click();
    },
    // 导入
    onImportEx(file) {
      const { files } = file.target;
      const fileReader = new FileReader(); // 创建FileReader 对象 读取文件
      fileReader.onload = (event) => {
        try {
          const { result } = event.target;
          // 二进制读取 excel表格对象
          const workList = XLSX.read(result, { type: "binary" });
          // 存储数据
          let data = [];
          for (let sheet in workList.Sheets) {
            if (workList.Sheets.hasOwnProperty(sheet)) {
              // 利用 sheet_to_json 方法将 excel 转成 json 数据
              data = data.concat(
                XLSX.utils.sheet_to_json(workList.Sheets[sheet])
              );
              // break; // 如果只取第一张表，就取消注释这行
            }
          }
          // 设置空值数组，处理过滤
          const empty = [null, "", undefined, NaN];
          // 最终获取到并且格式化后的 json 数据
          const tableData = data
            .map((item) => {
              return {
                userId: Number(item["职工号"]),
                userName: item["姓名"] || "",
                officialPhone: item["办公电话"] || "",
                phone: item["移动电话"] || "",
                remark: item["备注"] || "",
                $cellEdit: true,
              };
            })
            .filter((v) => !empty.includes(v.userId));

          // 导入数据检测
          this.checkImportData(tableData);
        } catch (error) {
          this.$message.error("导入失败!");
        }
      };
      fileReader.readAsBinaryString(files[0]);
    },
    // 下载导入模板
    downloadTemplate() {
      let url = "/template.xlsx";
      let a = document.createElement("a");
      a.href = url;
      a.download = "template.xlsx";
      a.style.display = "none";
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    },
    // 验证的导入数据
    checkImportData(xlsxData = []) {
      if (xlsxData.length === 0) return;

      // 检查用户列表
      const result = xlsxData.filter((item) => {
        const { userId = "" } = item;
        const d1 = this.userList.find((v) => v.userId == userId) || {};
        const d2 = this.tableData.find((v) => v.userId == userId) || {};
        return JSON.stringify(d1) !== "{}" && JSON.stringify(d2) === "{}";
      });

      // 判断数据
      if (xlsxData.length !== result.length) {
        this.$message.warning(
          "该文件存在未知的职工号、重复的数据，已自动剔除!"
        );
      }

      this.tableData = [...this.tableData, ...result];
      this.formatUserData();
    },
    // 获取用户
    async getUser() {
      const params = {
        deptId: this.userInfo.deptId,
      };
      const { code, data = [] } = await getUserList(params);
      this.userList = code === 200 ? data : [];
      code === 200 && this.formatUserData();
    },
    // 获取领导
    changeLeader(val, dic) {
      const item = dic.find((v) => v.userName === val) || {};
      if (JSON.stringify(item) !== "{}") {
        const { phonenumber = "", nickName = "", officialPhone = "" } = item;
        this.form = {
          ...this.form,
          leaderName: nickName,
          leaderPhone: phonenumber,
          leaderOfficialPhone: officialPhone,
        };
        setTimeout(() => {
          this.formatUserData();
        }, 400);
      }
    },
    // 格式化用户数据
    formatUserData() {
      // 数据为空，不处理
      if (this.userList.length === 0) return;
      const result = this.userList.map((item) => {
        const { userName = "" } = item;
        const { leaderId } = this.form;
        const d = this.tableData.find((v) => v.userId === userName) || {};
        item.disabled = false;
        if (Object.keys(d).length === 0) {
          item.disabled = false;
          if (userName === leaderId) {
            item.disabled = true;
          }
        } else {
          item.disabled = true;
        }
        return item;
      });
      this.userList = result;
    },
  },
  mounted() {
    this.loading = true;
    this.$nextTick(() => {
      const { scheduleType = "" } = this.row;
      const { deptId, dept: { deptName } = {} } = this.userInfo;
      this.form = {
        deptId,
        deptName,
        scheduleDay: this.scheduleDay,
        scheduleType,
      };
    });

    this.initData();
    this.getUser();
  },
};
</script>

<style lang="scss" scoped>
.my-dialog ::v-deep .el-dialog__body {
  margin-bottom: 0px !important;
}
</style>
